#!/usr/bin/env python2
#-*- coding: utf-8 -*-

"""
Created on 20160328
"""
import web
import os
import gettext
import urllib
import posixpath

from Umpweb.db import api as db_api
from Umpweb import defs
from Umpweb.common import config
from SimpleHTTPServer import SimpleHTTPRequestHandler

pwd_path = os.path.dirname(os.path.realpath(__file__))

#app_info = {
#    'mapping':urls,
#    'fvars':globals(),
#    'autoreload':True,
#}

class MyApplication(web.application):
    def run_(self, port=8080, *middleware):
        wsgifunc = self.wsgifunc(*middleware)
        return web.httpserver.runsimple(wsgifunc, ('0.0.0.0', port))

    def run(self, port=8080, *middleware):
        wsgifunc = self.wsgifunc(*middleware)
        wsgifunc = StaticMiddleware(wsgifunc)
        wsgifunc = web.httpserver.LogMiddleware(wsgifunc)
        server = web.httpserver.WSGIServer(("0.0.0.0", port), wsgifunc)
        try:
            server.start()
        except KeyboardInterrupt:
            server.stop()

class StaticApp(SimpleHTTPRequestHandler):
    """WSGI application for serving static files."""
    #SimpleHTTPRequestHandler rewirte ; not use translate_path instance method
    def __init__(self, environ, start_response):
        self.headers = []
        self.environ = environ
        self.start_response = start_response

    def send_response(self, status, msg=""):
        self.status = str(status) + " " + msg

    def send_header(self, name, value):
        self.headers.append((name, value))

    def end_headers(self):
        pass

    def log_message(*a): pass

    def __iter__(self):
        environ = self.environ

        self.path = environ.get('PATH_INFO', '')
        self.client_address = environ.get('REMOTE_ADDR','-'), \
                              environ.get('REMOTE_PORT','-')
        self.command = environ.get('REQUEST_METHOD', '-')

        from cStringIO import StringIO
        self.wfile = StringIO() # for capturing error

        try:
            #path = self.translate_path(self.path)
            path = self.absolute_path(self.path)   
            etag = '"%s"' % os.path.getmtime(path)
            client_etag = environ.get('HTTP_IF_NONE_MATCH')
            self.send_header('ETag', etag)
            if etag == client_etag:
                self.send_response(304, "Not Modified")
                self.start_response(self.status, self.headers)
                raise StopIteration
        except OSError,e:
            pass # Probably a 404

        f = self.send_head()
        self.start_response(self.status, self.headers)

        if f:
            block_size = 16 * 1024
            while True:
                buf = f.read(block_size)
                if not buf:
                    break
                yield buf
            f.close()
        else:
            value = self.wfile.getvalue()
            yield value

    def send_head(self):
        """Common code for GET and HEAD commands.
        
        This sends the response code and MIME headers.
        
        Return value is either a file object (which has to be copied
        to the outputfile by the caller unless the command was HEAD,
        and must be closed by the caller under all circumstances), or
        None, in which case the caller has nothing further to do.
        
        """
        #SimpleHTTPRequestHandler rewirte ; not use translate_path instance method
        #path = self.translate_path(self.path)   
        path = self.absolute_path(self.path)   
        f = None
        if os.path.isdir(path):
            if not self.path.endswith('/'):
                # redirect browser - doing basically what apache does
                self.send_response(301)
                self.send_header("Location", self.path + "/")
                self.end_headers()
                return None
            for index in "index.html", "index.htm":
                index = os.path.join(path, index)
                if os.path.exists(index):
                    path = index
                    break
            else:
                return self.list_directory(path)
        ctype = self.guess_type(path)
        try:
            # Always read in binary mode. Opening files in text mode may cause
            # newline translations, making the actual size of the content
            # transmitted *less* than the content-length!
            f = open(path, 'rb')
        except IOError:
            self.send_error(404, "File not found")
            return None
        self.send_response(200)
        self.send_header("Content-type", ctype)
        fs = os.fstat(f.fileno())
        self.send_header("Content-Length", str(fs[6]))
        self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
        self.end_headers()
        return f

    def absolute_path(self, path):
        path = os.path.join(pwd_path, path.lstrip(os.sep))
        return path



class StaticMiddleware:
    """WSGI middleware for serving static files."""
    def __init__(self, app, prefix='/static/', root_path=pwd_path):
        self.app = app 
        self.prefix = prefix
        self.root_path = root_path
    
    def __call__(self, environ, start_response):
        path = environ.get('PATH_INFO', '') 
        path = self.normpath(path)

        if path.startswith(self.prefix):
            return StaticApp(environ, start_response)
        else:
            return self.app(environ, start_response)

    def normpath(self, path):
        path2 = posixpath.normpath(urllib.unquote(path))
        if path.endswith("/"):
            path2 += "/" 
        return path2


web.config.debug = False 
web.config.session_parameters['secret_key'] = '%s_dashboard' % (defs.PRODUCT_NAME)
web.config.session_parameters['cookie_name'] = '%s_session_id' % (defs.PRODUCT_NAME)

webstor = web.utils.storage
session_info = {
    'store':web.session.DiskStore(os.path.join(pwd_path,'sessions')),
    'initializer':{
        'user':webstor({
            'id':None,
            'name':None,
            'is_login':0,
            'skin': None,
            'lang':'zh_CN',
            'token':None,
        }),
        'token':None,
        'mathine':None,
        'currmathine':None
    }}

session = None
def _init_session(app):
    global session
    if web.config.get('_session') is None:
        session_info['app'] = app
        session = web.session.Session(**session_info)
        web.config._session = session
    else:
        session = web.config._session
    return session


app = None
def init_app(urls):
    global app
    app = MyApplication(urls, globals(), True)
    return app


alltranslations = web.storage()
localedir = os.path.join(pwd_path,'pyi18n/i18n')
def get_translations(lang='zh_CN'):
    if lang in alltranslations:
        translation = alltranslations[lang]
    elif lang is None:
        translation = gettext.NullTranslations()
    else:
        try:
            translation = gettext.translation('messages', localedir,languages=[lang])
        except Exception,e:
            translation = gettext.NullTranslations()
    return translation

def load_translations(lang):
    lang = str(lang)
    translation = alltranslations.get(lang)
    if translation is None:
        translation = get_translations(lang)
        alltranslations[lang] = translation

        for lk in alltranslations.keys():
            if lk != lang:
                del alltranslations[lk]
    return translation

def custom_gettext(string):
    lang = 'zh_CN'
    
    if 'session' in globals() and 'user' in globals()['session'] and 'lang' in globals()['session'].user:
        lang = session.user.get('lang')
    translation = load_translations(lang)

    if translation is None:
        return unicode(string)
    return translation.ugettext(string)

global _
_ = custom_gettext


def get_http_host():
    http_host = web.ctx.env.get('HTTP_HOST','')
    return http_host.split(':')[0]

def striptags(s):
    return s.lstrip('<').rstrip('>')

is_fusionnas = (defs.PRODUCT_NAME == 'fusionnas')

class render_jinja:
    """Rendering interface to Jinja2 Templates
    
    Example:

        render= render_jinja('templates')
        render.hello(name='jinja2')
    """
    def __init__(self, *a, **kwargs):
        a = (os.path.join(pwd_path, a[0]), ) + a[1:-1]
        extensions = kwargs.pop('extensions', []) 
        globals = kwargs.pop('globals', {}) 

        from jinja2 import Environment,FileSystemLoader
        self._lookup = Environment(loader=FileSystemLoader(*a, **kwargs), extensions=extensions)
        self._lookup.globals.update(globals)
    
    def __getattr__(self, name):
        # Assuming all templates end with .html
        path = name + '.html'
        t = self._lookup.get_template(path)
        self.set_render_globals()
        return t.render

    def set_render_globals(self):
        self._lookup.globals.update(_ = _)
        self._lookup.globals.update(is_fusionnas = is_fusionnas)
        self._lookup.globals.update(session=session)
        self._lookup.globals.update(config=config)
        self._lookup.globals.update(check_permission=db_api.check_permission)
        self._lookup.globals.update(check_is_adminstrator=db_api.check_is_adminstrator)
        self._lookup.globals.update(http_host=get_http_host())
        self._lookup.globals.update(striptags=striptags)
